﻿using Dong.Model;
using Stote.UControls;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Stote.Forms
{
    public partial class FrmTemperature : Form
    {
        Dong.BLL.StoreArea storeAreaBLL = new Dong.BLL.StoreArea();
        Dong.BLL.Store storeBLL = new Dong.BLL.Store();

        public FrmTemperature()
        {
            InitializeComponent();

            Load += FrmTemperature_Load;
            btnCheck.Click += BtnCheck_Click;
            serialPort1 = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
            serialPort1.DataReceived += SerialPort1_DataReceived;
        }

        private void FrmTemperature_Load(object sender, EventArgs e)
        {
            BindStore();
            lblMsg.Text = string.Empty;
        }

        private void BindStore()
        {
            DataSet ds = storeBLL.GetList(" Status=0");
            DataTable dt = ds.Tables[0];
            DataRow dr = dt.NewRow();
            dr["StoreId"] = -1;
            dr["StoreName"] = "全部";
            dt.Rows.InsertAt(dr, 0);
            cbStore.DataSource = dt;
            cbStore.DisplayMember = "StoreName";
            cbStore.ValueMember = "StoreId";
        }

        private async void BtnCheck_Click(object sender, EventArgs e)
        {
            try
            {
                lblMsg.ForeColor = Color.Black;
                lblMsg.Text = "开始检测，请稍候...";
                btnCheck.Enabled = false;
                if (!serialPort1.IsOpen) serialPort1.Open();
                byte[] k = new byte[6] { 0X01, 0X03, 0X00, 0X00, 0X00, 0X01 }; // 准备读取温度的数据帧
                byte[] r = Crc16(k);
                byte[] buffer = new byte[8];
                Array.Copy(k, 0, buffer, 0, 6);
                Array.Copy(r, 0, buffer, 6, 2);
                serialPort1.Write(buffer, 0, buffer.Length);
                await Task.Delay(1000);
                if (serialPort1.IsOpen)
                {
                    if (serialPort1.BytesToRead == 0)
                    {
                        lblMsg.ForeColor = Color.Red;
                        lblMsg.Text = "请连接设备！";
                        btnCheck.Enabled = true;
                        flowLayoutPanel1.Controls.Clear();
                    }
                    serialPort1.Close();
                }
            }
            catch (Exception ex)
            {
                lblMsg.ForeColor = Color.Red;
                lblMsg.Text = "手工检测失败！";
                btnCheck.Enabled = true;
                if (serialPort1.IsOpen) serialPort1.Close();
                MessageBox.Show($"手工检测失败！失败原因：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] buffer = new byte[serialPort1.BytesToRead];
            int len = serialPort1.Read(buffer, 0, buffer.Length);
            if (len == 7)
            {
                decimal temperature = (buffer[3] * 256 + buffer[4]) / 10M; // 读取到的温度值

                Invoke(new Action(() =>
                {
                    int storeId = Convert.ToInt32(cbStore.SelectedValue);
                    string strWhere = string.Empty;
                    if (storeId != -1) strWhere = $"StoreId={storeId}";
                    List<StoreArea> modelList = storeAreaBLL.GetModelList(strWhere);
                    foreach (StoreArea model in modelList)
                    {
                        model.Temperature = temperature;
                        storeAreaBLL.Update(model);  // 更新数据库
                    }
                    List<StoreAreaBoxModel> list = storeAreaBLL.GetStoreAreaBoxList(strWhere);
                    ShowList(list); // 展示数据
                }));
            }
            Invoke(new Action(() =>
            {
                lblMsg.ForeColor = Color.Black;
                lblMsg.Text = "手工检测完成！";
                btnCheck.Enabled = true;
            }));
            serialPort1.Close();
        }

        private void ShowList(List<StoreAreaBoxModel> list)
        {
            flowLayoutPanel1.Controls.Clear();
            foreach (StoreAreaBoxModel model in list)
            {
                UCStoreAreaBox box = new UCStoreAreaBox();
                box.UBoxSource = model;
                if (box.TemperatureState != 0)
                {
                    box.SetTemperature += SetTemperature;//订阅事件
                }
                flowLayoutPanel1.Controls.Add(box);
            }
        }

        private void SetTemperature(object sender, EventArgs args)
        {
            FrmSetTemperature form = new FrmSetTemperature()
            {
                Tag = (((sender as Button).Parent.Parent) as UCStoreAreaBox).UBoxSource,
            };
            if (form.ShowDialog() == DialogResult.OK)
            {
                btnCheck.PerformClick();
            }
        }

        private byte[] Crc16(byte[] data)
        {
            //1 初始化一个16位的寄存器地址 用作初始值
            int crc = 0xffff;
            //2 遍历数据字节
            for (int i = 0; i < data.Length; i++)
            {
                //3 将数据字节与寄存器异或
                crc = crc ^ data[i];
                //4 对寄存器进行8次迭代，每一次迭代将寄存器右移一位
                for (int j = 0; j < 8; j++)
                {
                    int temp;
                    temp = crc & 1;
                    crc = crc >> 1;//每一次迭代将寄存器右移一位
                    crc = crc & 0x7fff;
                    //5 如果最低位位1，将寄存器与生成多项式0x8005异或，否则只进行右移操作
                    if (temp == 1) crc = crc ^ 0xa001;
                    crc = crc & 0xffff;
                }
            }
            byte[] crc16 = new byte[2];// crc寄存器的高低为进行互换
            crc16[1] = (byte)((crc >> 8) & 0xff); //crc寄存器高八位变成了八低位
            crc16[0] = (byte)(crc & 0xff);// crc寄存器低八位变成了高低位
            return crc16;
        }
    }
}
